package org.jsola.hr.service.impl;

import com.alibaba.fastjson.JSON;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.jsola.core.Page;
import org.jsola.hr.common.ExampleKit;
import org.jsola.hr.constant.HrConstants;
import org.jsola.hr.dao.IAttendShiftDAO;
import org.jsola.hr.dto.AttendShiftAddDTO;
import org.jsola.hr.dto.AttendShiftUpdateDTO;
import org.jsola.hr.dto.attendschedule.AttendPeriodDTO;
import org.jsola.hr.dto.attendschedule.AttendShiftSaveDTO;
import org.jsola.hr.entity.AttendShiftDO;
import org.jsola.hr.entity.AttendShiftStaffScheduleDO;
import org.jsola.hr.entity.EmpDepDO;
import org.jsola.hr.query.AttendShiftQuery;
import org.jsola.hr.query.AttendShiftStaffScheduleQuery;
import org.jsola.hr.query.EmpDepQuery;
import org.jsola.hr.service.IAttendShiftService;
import org.jsola.hr.service.IAttendShiftStaffScheduleService;
import org.jsola.hr.service.IEmpDepService;
import org.jsola.hr.vo.AttendShiftListVO;
import org.jsola.hr.vo.AttendShiftVO;
import org.jsola.user.core.TokenUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.entity.Example;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author zhr
 */
@Service("hrAttendShiftServiceImpl")
public class AttendShiftServiceImpl implements IAttendShiftService {

    @Autowired
    private IAttendShiftDAO attendShiftDAO;
    @Autowired
    private IAttendShiftStaffScheduleService attendShiftStaffScheduleService;
    @Autowired
    private IEmpDepService empDepService;

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public AttendShiftVO save(AttendShiftAddDTO attendShiftAddDTO, TokenUser tokenUser) {
        // 转DO
        AttendShiftDO attendShiftDO = attendShiftAddDTO.to(AttendShiftDO.class);
        // 保存
        attendShiftDO = save(attendShiftDO, tokenUser.getSiteId(), tokenUser.getUserId());
        return attendShiftDO.to(AttendShiftVO.class);
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public int update(AttendShiftUpdateDTO attendShiftUpdateDTO, TokenUser tokenUser) {
        //转DO
        AttendShiftDO attendShiftDO = attendShiftUpdateDTO.to(AttendShiftDO.class);
        //根据主键更新，只更新非null值
        return updateByIdSelective(attendShiftDO, tokenUser.getSiteId(), tokenUser.getUserId());
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public int deleteByIds(TokenUser tokenUser, String... attendShiftIds) {
        return logicalDeleteByIds(tokenUser.getSiteId(), tokenUser.getUserId(), (Object[]) attendShiftIds);
    }


    @Override
    public AttendShiftVO selectById(String attendShiftId, String siteId) {
        AttendShiftDO attendShiftDO = selectDOById(attendShiftId, siteId);
        if (attendShiftDO == null) {
            return null;
        }
        return attendShiftDO.to(AttendShiftVO.class);
    }

    @Override
    public List<AttendShiftListVO> select(AttendShiftQuery attendShiftQuery, String siteId) {
        List<AttendShiftDO> attendShiftDOList = selectDO(attendShiftQuery, siteId);
        if(CollectionUtils.isEmpty(attendShiftDOList)) {
            return attendShiftDOList == null ? null : new ArrayList<>();
        }
        return attendShiftDOList.stream()
                .map(attendShiftDO -> attendShiftDO.to(AttendShiftListVO.class))
                .collect(Collectors.toList());
    }

    @Override
    public int selectCount(AttendShiftQuery attendShiftQuery, String siteId) {
        Example example = buildExample(attendShiftQuery,siteId);
        return attendShiftDAO.selectCountByExample(example);
    }

    @Override
    public Page<AttendShiftListVO> selectPage(AttendShiftQuery attendShiftQuery, String siteId) {
        Example example = buildExample(attendShiftQuery,siteId);
        Page<AttendShiftDO> page = attendShiftDAO.selectPageByExample(example,
                attendShiftQuery.getPageNo(),
                attendShiftQuery.getPageSize());

        return page.to(AttendShiftListVO.class);
    }

    @Override
    public AttendShiftDO selectDOById(String attendShiftId, String siteId) {
        return listById(attendShiftId, siteId);
    }

    @Override
    public List<AttendShiftDO> selectDO(AttendShiftQuery attendShiftQuery, String siteId) {
        Example example = buildExample(attendShiftQuery,siteId);
        return attendShiftDAO.selectByExample(example);
    }

    @Override
    public int deleteByAttendPlanId(String attendPlanId, TokenUser tokenUser) {

        AttendShiftQuery attendShiftQuery = new AttendShiftQuery();
        attendShiftQuery.setAttendPlanId(attendPlanId);
        Example example = buildExample(attendShiftQuery,tokenUser.getSiteId());
        return attendShiftDAO.deleteByExample(example);
    }

    @Override
    public int updateAttendPlanId(String tmpAttendPlanId, String attendPlanId, TokenUser tokenUser) {

        AttendShiftQuery attendShiftQuery = new AttendShiftQuery();
        attendShiftQuery.setAttendPlanId(tmpAttendPlanId);
        Example example = buildExample(attendShiftQuery, tokenUser.getSiteId());

        AttendShiftDO record = new AttendShiftDO();
        record.setAttendPlanId(attendPlanId);

        return attendShiftDAO.updateByExampleSelective(record, example);
    }

    /**
     * 按班次上下班的打卡时间
     *
     * @param attendPlanId
     * @param empInfoId
     * @param tokenUser
     * @return
     */
    @Override
    public AttendShiftSaveDTO getAttendShift(String attendPlanId, String empInfoId, String attendDateStr, TokenUser tokenUser) {

        AttendShiftSaveDTO attendShiftSaveDTO = null;
        AttendShiftStaffScheduleDO attendShiftStaffSchedule = null;

        // 年月日
        String yearly = attendDateStr.split("-")[0];
        String monthly = attendDateStr.split("-")[1];
        String daily = attendDateStr.split("-")[2];

        // 根据考勤规则ID查询考勤人员排班表
        AttendShiftStaffScheduleQuery attendShiftStaffScheduleQuery = new AttendShiftStaffScheduleQuery();
        attendShiftStaffScheduleQuery.setAttendPlanId(attendPlanId);
        attendShiftStaffScheduleQuery.setEmpInfoId(empInfoId);
        attendShiftStaffScheduleQuery.setYearly(yearly);
        attendShiftStaffScheduleQuery.setMonthly(monthly);
        attendShiftStaffScheduleQuery.setDaily(daily);
        List<AttendShiftStaffScheduleDO> attendShiftStaffScheduleList = attendShiftStaffScheduleService.selectDO(attendShiftStaffScheduleQuery, tokenUser.getSiteId());
        if (attendShiftStaffScheduleList.size() <= 0) {

            // 查询考勤人员所在部门
            EmpDepQuery empDepQuery = new EmpDepQuery();
            empDepQuery.setEmpId(empInfoId);
            List<EmpDepDO> empDepList = empDepService.selectDO(empDepQuery, tokenUser.getSiteId());
            if (empDepList.size() <= 0) {
                return null;
            }

            // 查询部门是否在考勤人员排班表
            for (EmpDepDO empDep : empDepList) {
                attendShiftStaffScheduleQuery = new AttendShiftStaffScheduleQuery();
                attendShiftStaffScheduleQuery.setAttendPlanId(attendPlanId);
                attendShiftStaffScheduleQuery.setEmpInfoId(empInfoId);
                attendShiftStaffScheduleQuery.setYearly(yearly);
                attendShiftStaffScheduleQuery.setMonthly(monthly);
                attendShiftStaffScheduleQuery.setDaily(daily);
                attendShiftStaffScheduleList = attendShiftStaffScheduleService.selectDO(attendShiftStaffScheduleQuery, tokenUser.getSiteId());
                if (attendShiftStaffScheduleList.size() <= 0) {
                    return null;
                }
                else {
                    attendShiftStaffSchedule = attendShiftStaffScheduleList.get(0);
                }
            }

            return null;
        }
        else {
            attendShiftStaffSchedule = attendShiftStaffScheduleList.get(0);
        }

        // 查询考勤班次
        AttendShiftQuery attendShiftQuery = new AttendShiftQuery();
        attendShiftQuery.setAttendPlanId(attendPlanId);
        attendShiftQuery.setName(attendShiftStaffSchedule.getAttendShiftName());
        List<AttendShiftDO> attendShiftList = this.selectDO(attendShiftQuery, tokenUser.getSiteId());
        if (attendShiftList.size() <= 0) {
            return null;
        }

        AttendShiftDO attendShiftDO = attendShiftList.get(0);
        attendShiftSaveDTO = attendShiftDO.to(AttendShiftSaveDTO.class);
        attendShiftSaveDTO.setAttendPeriodList(JSON.parseArray(attendShiftDO.getPeriodJson(), AttendPeriodDTO.class));
        attendShiftSaveDTO.setAttendPunchTimeId(attendShiftDO.getId());

        return attendShiftSaveDTO;
    }

    @Override
    public int logicDelByAttendPlanId(String attendPlanId, TokenUser tokenUser) {

        // 查询
        AttendShiftQuery attendShiftQuery = new AttendShiftQuery();
        attendShiftQuery.setAttendPlanId(attendPlanId);
        List<AttendShiftDO> dataList = this.selectDO(attendShiftQuery, tokenUser.getSiteId());
        if (dataList.size() <= 0) {
            return 0;
        }

        for (AttendShiftDO attendShift : dataList) {

            AttendShiftDO attendShiftDO = new AttendShiftDO();
            attendShiftDO.setId(attendShift.getId());
            attendShiftDO.setValid(false);
            attendShiftDO.setModifiedUserId(tokenUser.getUserId());
            attendShiftDO.setGmtModified(new Date());
            attendShiftDAO.updateByPrimaryKeySelective(attendShiftDO);
        }

        return 0;
    }

    /**
     * 根据查询参数，构建example

     * @param attendShiftQuery 查询参数
     * @param siteId 所属站点id
     * @return example
     */
    private Example buildExample(AttendShiftQuery attendShiftQuery, String siteId) {
        Example example = new Example(AttendShiftDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("siteId", siteId);
        if (attendShiftQuery.getNameList() != null && attendShiftQuery.getNameList().size() > 0) {
            example.and().andIn("name", attendShiftQuery.getNameList());
        }
        if (attendShiftQuery.getAttendPlanId() != null) {
            example.and().andEqualTo("attendPlanId", attendShiftQuery.getAttendPlanId());
        }
        if (attendShiftQuery.getName() != null) {
            example.and().andEqualTo("name", attendShiftQuery.getName());
        }
        if (attendShiftQuery.getPeriodJson() != null) {
            example.and().andEqualTo("periodJson", attendShiftQuery.getPeriodJson());
        }
        if (attendShiftQuery.getIsAdvanc() != null) {
            example.and().andEqualTo("isAdvanc", attendShiftQuery.getIsAdvanc());
        }
        if (attendShiftQuery.getIsAllowedLateEarly() != null) {
            example.and().andEqualTo("isAllowedLateEarly", attendShiftQuery.getIsAllowedLateEarly());
        }
        if (attendShiftQuery.getLateMinute() != null) {
            example.and().andEqualTo("lateMinute", attendShiftQuery.getLateMinute());
        }
        if (attendShiftQuery.getEarlyMinute() != null) {
            example.and().andEqualTo("earlyMinute", attendShiftQuery.getEarlyMinute());
        }
        if (attendShiftQuery.getIsAllowLateLate() != null) {
            example.and().andEqualTo("isAllowLateLate", attendShiftQuery.getIsAllowLateLate());
        }
        if (attendShiftQuery.getOffWorkLateMinute() != null) {
            example.and().andEqualTo("offWorkLateMinute", attendShiftQuery.getOffWorkLateMinute());
        }
        if (attendShiftQuery.getOnWorkLateMinute() != null) {
            example.and().andEqualTo("onWorkLateMinute", attendShiftQuery.getOnWorkLateMinute());
        }
        if (attendShiftQuery.getEarliestPunchTime() != null) {
            example.and().andEqualTo("earliestPunchTime", attendShiftQuery.getEarliestPunchTime());
        }
        if (attendShiftQuery.getLatestPunchTime() != null) {
            example.and().andEqualTo("latestPunchTime", attendShiftQuery.getLatestPunchTime());
        }
        if (attendShiftQuery.getAfterWorkNeedPunch() != null) {
            example.and().andEqualTo("afterWorkNeedPunch", attendShiftQuery.getAfterWorkNeedPunch());
        }
        // 排序
        ExampleKit.setExampleOrder(example,attendShiftQuery.getOrders());
        return example;
    }
}




